package com.justdoit.facedemo.utils;

// 这个静态的jar包需要你手动引入

import com.arcsoft.face.toolkit.ImageInfo;
import com.arcsoft.face.toolkit.ImageInfoEx;
import lombok.Data;

import java.io.File;
import java.io.InputStream;

import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;


/**
 * 不同类型（二进制、Stream流、File文件、）照片处理类
 * 返回 ImageInfoMeta 类，其中包含了两个成员变量：原始图片数据，包装后数据
 */
public class ArcFaceUtils {
    /**
     * 处理 File 的图片流
     *
     * @param img 要进行人脸识别的图片
     * @return 返回封装了两个图片包装类，的类
     */
    public static ImageInfoMeta packImageInfoEx(File img) {

        // 用来包装你的图片流对象，比如需要检测人脸的照片，或者证件照，详情参考 “常用包” 笔记
        ImageInfo imageInfo = getRGBData(img);

        // 对最基础的包装类，再次进行包装，及一些其他的初始化
        return packImageInfoMeta(imageInfo);
        //初始化好之后，可以得到一个封装了两个包装类的类，并返回
    }

    /**
     * 处理 byte[] 的图片流
     * <p>
     * 就是设置一个视频中，隔多少帧，抽取一个画面（通过第三方库实现，比如JavaCV，或前端传递）
     * 然后 通过 byte数据流 传入给这个方法，进行人脸信息提取
     *
     * @param img byte类型的图片数据数据流
     * @return 返回封装了两个图片包装类的封装对象
     */
    public static ImageInfoMeta packImageInfoMeta(final byte[] img) {

        // 重载方法
        ImageInfo imageInfo = getRGBData(img);
        return packImageInfoMeta(imageInfo);
    }

    /**
     * 处理 InputStream 的图片流
     *
     * @param img InputStream类型的 图片/视频 数据流
     * @return 返回封装了两个图片包装类的封装对象
     */
    public static ImageInfoMeta packImageInfoMeta(InputStream img) {

        // 重载方法
        ImageInfo imageInfo = getRGBData(img);
        return packImageInfoMeta(imageInfo);
    }


    /**
     * 打包生成 ImageInfoMeta
     *
     * @param imageInfo 最初始的图片包装类
     * @return 返回一个包装类
     */
    private static ImageInfoMeta packImageInfoMeta(ImageInfo imageInfo) {

        // 自定义的 静态内部类，这个类用来初始化的 位于 ArcFaceWorker 类中
        ImageInfoMeta imageInfoMeta = new ImageInfoMeta(imageInfo);

        // 返回这个保存了两个包装类，的类
        return imageInfoMeta;
    }

    /**
     * 对imageInfo 和 imageInfoEx 的打包对象
     */
    @Data
    public static class ImageInfoMeta {
        private ImageInfo imageInfo;     // 最初始包装类
        private ImageInfoEx imageInfoEx; // 二次包装类

        public ImageInfoMeta(ImageInfo imageInfo) {

            //  将初始的包装类保存好
            this.imageInfo = imageInfo;

            // 将最初始包装好的 ImageInfo 对象， 使用 ImageInfoEx 进行包装
            imageInfoEx = new ImageInfoEx();
            imageInfoEx.setHeight(imageInfo.getHeight());
            imageInfoEx.setWidth(imageInfo.getWidth());
            imageInfoEx.setImageFormat(imageInfo.getImageFormat());
            imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
            imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});
        }
    }

}
